package cn.duxiaod.demo.threadpool;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        /**
         * 1、核心参数有：核心线程数，最大线程数,存活时间，存货时间单位，队列大小，拒绝策略（四种）
         *
         * 2、如何确定线程数：
         * IO密集型2n+1，n为核心数；CPU密集型n+1；或者根据阻塞系数0.8-0.9，线程数=CPU核心数/(1-阻塞系数)。
         *
         * 3、怎么判断需要增加更多线程呢？
         * 其实可以用jstack命令查看一下进程的线程栈，如果发现线程池中大部分线程都处于等待获取任务，则说明线程够用；
         * 如果大部分线程都处于运行状态，可以继续适当调高线程数量。
         *
         * 4、拒绝策略：
         * AbortPolicy，默认策略，抛出异常rejectedException
         * DiscardPolicy，新任务无法加入队列，直接抛弃
         * DiscardOldestPolicy，无法计入队列时抛弃下一个执行，再提交最新的
         * CallerRunsPolicy，主线程直接执行该任务，执行完之后尝试添加下一个任务到线程池中，可以有效降低向线程池内添加任务的速度
         */
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5,
                10,
                1,
                TimeUnit.MINUTES ,
                new LinkedBlockingDeque<>(2),
                new NamedThreadFactory("自定已线程池"));
        ThreadPoolExecutor poolExecutor2 = new ThreadPoolExecutor(5,
                10,
                1,
                TimeUnit.MINUTES ,
                new LinkedBlockingDeque<>(2),
                new NamedThreadFactory("自定已线程池"));
        for(int i=0;i<20;i++){
            poolExecutor.execute(new RunnableTest(poolExecutor));
            poolExecutor2.execute(new RunnableTest(poolExecutor));
        }
    }
}

class RunnableTest implements Runnable{

    ThreadPoolExecutor poolExecutor;

    public RunnableTest(  ThreadPoolExecutor poolExecutor){
        this.poolExecutor=poolExecutor;
    }

    @Override
    public void run() {
        int threadSize=this.poolExecutor.getActiveCount();
        int queueCurrentSize=this.poolExecutor.getQueue().size();
        System.out.println(Thread.currentThread().getName()+":执行开始："+"当前线程数："+threadSize+"当前队列大小："+queueCurrentSize);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
